#!/usr/bin/env node

const http = require('http');
const log = console.log;
const cp = require('child_process');

http.createServer(async (req, res) => {
    res.setHeader('Access-Control-Allow-Origin', '*'); // 跨域策略的设置

    if (req.method === 'POST' && req.url === '/') {
        try {
            const result = await exec(req);
            res.end(templatePage().replace('__result', result));
        } catch (error) {
            res.statusCode = 500;
            res.end('Internal Server Error: ' + error.message);
        }
        return;
    }
    if (req.method === 'GET' && req.url === '/') {
        res.end(emptyPage());
        return;
    }
    res.statusCode = 404;
    res.end(errorPage());
}).listen(3000);

function errorPage() {
    return '<body><h1>Not Found!</h1></body>';
}

function templatePage() {
    return `
        <!DOCTYPE html>
        <html lang="en">
        <head>
            <meta charset="UTF-8">
            <meta name="viewport" content="width=device-width, initial-scale=1.0">
            <title>linux命令行</title>
        </head>
        <body>
            <h1>Input linux commmand</h1>
            <form method="POST" action="/">
                <label>命令：</label>
                <input type="text" name="cmd"/>
                <input type="submit" value="执行"/>
            </form>
            <pre>__result</pre>
        </body>
        </html>
    `;
}
function emptyPage() {
    return templatePage().replace('__result', '');
}

async function exec(req) {
    return new Promise((resolve, reject) => {
        log(`${req.method} ${req.url} ${req.headers['user-agent']}`);
        let cmd = '';
        req.on('data', chunk => cmd += chunk);
        req.on('end', () => {
            cmd = new URLSearchParams(cmd).get('cmd');
            cp.exec(cmd, (err, out, errMsg) => {
                if (err) {
                    res.statusCode = 500;
                    res.end('error:', err.message);
                } else {
                    resolve(out.toString());
                }
            });
        });
    });
}

async function resultPage(req) {
    const result = await exec(req);
    return templatePage().replace('__result', result);
}